Skip to content

Extended error handling when a node fails#64

Merged
jonatan-qm merged 31 commits into
mainfrom
feat/extended-error-handling
Jan 6, 2026
Merged

Extended error handling when a node fails#64
jonatan-qm merged 31 commits into
mainfrom
feat/extended-error-handling

Conversation

@jonatan-qm

@jonatan-qm jonatan-qm commented Nov 26, 2025

Copy link
Copy Markdown
Contributor

Part of solving https://quantum-machines.atlassian.net/browse/QUAL-1645

Enhances error reporting by extending the RunError model with optional details_headline and details fields. When nodes raise errors, these fields propagate structured error information for better debugging and frontend display.

A major part of the work here is adding comprehensive testing, including node end-to-end tests. The tests depends on qualibrate-core, so this PR will have failing tests until the qua-platform/qualibrate-core#143 PR in qualibrate-core has been merged!

Key Changes

  • Extended RunError model: Added details_headline and details fields to capture structured error information from node exceptions
  • Error propagation: Modified run_node() in run_job.py to extract and propagate error details from node run_summary.error to RunError
  • Comprehensive testing: Added extensive unit tests (config state, models, run_job) and integration tests that execute real test nodes
  • Documentation: Added explanatory comments throughout core modules
  • Minor fixes: Replaced deprecated HTTP_422_UNPROCESSABLE_ENTITY with HTTP_422_UNPROCESSABLE_CONTENT

Test Coverage

  • Unit tests: config state, models (common, last_run), and run_job execution
  • Integration tests: end-to-end node execution with test fixtures
  • Test fixtures: reusable test nodes including error-raising scenarios

@jonatan-qm jonatan-qm self-assigned this Nov 26, 2025
@jonatan-qm jonatan-qm marked this pull request as ready for review November 27, 2025 09:54
Comment thread tests/conftest.py
Comment thread tests/conftest.py
Comment thread tests/conftest.py
Comment thread tests/conftest.py
Comment thread tests/conftest.py
Comment thread tests/fixtures/test_nodes/node_with_actions.py
Comment thread tests/fixtures/test_nodes/node_with_subroutine.py
Comment thread tests/fixtures/test_nodes/node_with_actions.py
Comment thread tests/fixtures/test_nodes/test_node_can_raise_in_body.py
description="Error message to use",
)
error_type: str = Field(
default="ValueError",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could use exception type instead of string here and then when we check we dont need to compare strings

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is useful to be able to insert a string here - in particular for the manual testing when running this node via the frontend.

Comment thread tests/conftest.py Outdated
Scope is explicitly set to "function" to ensure each test gets fresh
node instances, maintaining test independence.
"""
from qualibrate import QualibrationLibrary

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an advantage putting it locally in the fixture?
we might use it in the future in more fixtures so maybe we should change the locations of the local imports to the whole file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - simplifying it now, putting imports at the top of the file.

Comment thread tests/conftest.py Outdated


@pytest.fixture(scope="function")
def test_library() -> Any:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it Any? don't we return QualibrationLibrary?
in general typing needs to be added in code wherever we can avoid using Any.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right! Fixing it.

"""Integration tests for simple nodes without action system."""

def test_simple_node_success(
self, test_library: Any, fresh_state: Any

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type hinting

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right! Fixing it.

self, test_library: Any, fresh_state: Any
) -> None:
"""Test successful execution of simple node."""
node = test_library.nodes["node_raises_in_body"]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should change the name of the node because from the name it sounds like this node should raise an exception from body, but we actually test the node runs successfully

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the name to node_can_raise_in_body

from qualang_tools.results import progress_counter
from qualang_tools.units import unit
from qualibrate import NodeParameters, QualibrationNode
from qualibration_libs.data import XarrayDataFetcher

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we remove dependency in qualibration_libs this should be taken in count aswell i assume

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread tests/unit/test_models_last_run.py Outdated
assert last_run.name == long_name
assert len(last_run.name) > 300

def test_many_state_updates(self, aware_datetime: Any) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it unnecessary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right! I deleted the test.

Comment thread tests/unit/test_models_last_run.py Outdated

assert len(last_run.state_updates) == 50

def test_complex_passed_parameters(self, aware_datetime: Any) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it unnecessary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right! I deleted the test.

Comment thread tests/unit/test_run_job.py
Comment thread tests/unit/test_run_job.py Outdated
assert fresh_state.last_run.error is None

@patch("qualibrate_runner.core.run_job.get_active_library_or_error")
def test_captures_workflow_snapshot_idx(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this tests after all the previous ones? if i understood right we checked it in the previous tests

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - I deleted the test.

Comment thread pyproject.toml Outdated
freezegun = "^1.2.0"
xarray = "^2024.1.0"
quam-builder = {git = "https://github.com/qua-platform/quam-builder.git"}
#qualibration-libs = {path = "../qualibration-libs", develop = true}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should remove dependency of qualibration-libs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@jonatan-qm jonatan-qm merged commit f36dc06 into main Jan 6, 2026
2 of 3 checks passed
@jonatan-qm jonatan-qm deleted the feat/extended-error-handling branch January 6, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants